package gov.nasa.anml.lifted;

import java.util.ArrayList;

import gov.nasa.anml.PDDL;
import gov.nasa.anml.State;
import gov.nasa.anml.PDDL.CompoundEffect;
import gov.nasa.anml.PDDL.Time;
import gov.nasa.anml.utility.SimpleBoolean;
import static gov.nasa.anml.lifted.ANMLBoolean.*;

public class WhenElseStatement extends WhenStatement {
	public Statement sElse;
	
	public boolean apply(State p, int contextID,State c) {
		if (guard.value(p)==True)
			return sThen.apply(p,contextID,c);
		else
			return sElse.apply(p,contextID,c);
	}
	
	public WhenElseStatement(Expression<SimpleBoolean,?> guard,Statement sThen,Statement sElse) {
		super(guard,sThen);
		this.sElse = sElse;
	}
	
	public Statement addStatement(Statement s) {
		if (sThen == null)
			return sThen = s;
		if (sElse == null)
			return sElse = s;
		return null;
	}
	
	public void translateDecl(PDDL pddl, Interval unit) {
		guard.translateDecl(pddl,unit);
		sThen.translateDecl(pddl,unit);
		sElse.translateDecl(pddl,unit);
	}
	
	public void translateStmt(PDDL pddl, Interval unit, Time part) {
		ArrayList<PDDL.BooleanExpression> conditions = unit.getPDDLConditions(); 
		ArrayList<PDDL.Effect> effects = unit.getPDDLEffects();
		
		IntervalImp iThen = new IntervalImp(unit);
		iThen.copyPDDL(unit);
		iThen.pddlConditions = new ArrayList<PDDL.BooleanExpression>();
		iThen.pddlEffects = new ArrayList<PDDL.Effect>();

		guard.translateStmt(pddl,iThen,part);
		
		PDDL.BooleanExpression head; 
		if (iThen.pddlConditions.size() == 1) {
			head = iThen.pddlConditions.get(0);
			iThen.pddlConditions.clear();
		} else {
			head = pddl.wrap(PDDL.Op.and,iThen.pddlConditions);
			iThen.pddlConditions = new ArrayList<PDDL.BooleanExpression>();
		}
		
		unit.getPDDLEffects().addAll(iThen.pddlEffects);
		iThen.pddlEffects.clear();
		
		sThen.translateStmt(pddl,iThen,part);
		
		switch(iThen.pddlConditions.size()) {
		case 0:
			break;
		case 1:
			conditions.add(pddl.makeTest(PDDL.Op.implies,head,iThen.pddlConditions.get(0)));
			break;
		default:
			conditions.add(pddl.makeTest(PDDL.Op.implies,head,pddl.wrap(PDDL.Op.and,iThen.pddlConditions)));
		}
		switch(iThen.pddlEffects.size()) {
		case 0:
			break;
		case 1:
			effects.add(pddl.new ConditionalEffect(head,iThen.pddlEffects.get(0)));
			break;
		default:
			effects.add(pddl.new ConditionalEffect(head,pddl.wrap(PDDL.Op.and,iThen.pddlEffects)));
		}
		
		head = pddl.negate(head);
		
		IntervalImp iElse = new IntervalImp(unit);
		iElse.copyPDDL(unit);
		iElse.pddlConditions = new ArrayList<PDDL.BooleanExpression>();
		iElse.pddlEffects = new ArrayList<PDDL.Effect>();
		sElse.translateStmt(pddl,iElse,part);
		
		switch(iElse.pddlConditions.size()) {
		case 0:
			break;
		case 1:
			conditions.add(pddl.makeTest(PDDL.Op.implies,head,iElse.pddlConditions.get(0)));
			break;
		default:
			conditions.add(pddl.makeTest(PDDL.Op.implies,head,pddl.wrap(PDDL.Op.and,iElse.pddlConditions)));
		}
		switch(iElse.pddlEffects.size()) {
		case 0:
			break;
		case 1:
			effects.add(pddl.new ConditionalEffect(head,iElse.pddlEffects.get(0)));
			break;
		default:
			effects.add(pddl.new ConditionalEffect(head,pddl.wrap(PDDL.Op.and,iElse.pddlEffects)));
		}
		
	}


}
